﻿using System.Collections;
using System.Collections.Generic;
using System;
using System.Linq;
using System.Text;
using KBEngine;

namespace KBEngine
{
    /// <summary>
    /// 事件中转器，把引擎SDK和客户端之间的事件进行强类型关联，并避免事件名的冲突
    /// </summary>
    public abstract class EventRouter
    {
        protected EventRouter()
        {
        }

        public virtual bool Check(List<string> existEvents)
        {
            List<string> myEventNames = GetEventNames();
            for (int i = 0; i < myEventNames.Count; i++)
            {
                string name = myEventNames[i];
                if (existEvents.Contains(name))
                {
                    Logger.LogError(string.Format("在类{0}中存在名为{1}的事件名，不可重复!", this.GetType().Name, name));
                    return false;
                }
                existEvents.Add(name);
            }
            return true;
        }

        protected virtual List<string> GetEventNames()
        {
            List<string> myEventNames = new List<string>();
            var ts = this.GetType().GetNestedTypes(System.Reflection.BindingFlags.Public);
            foreach (var t in ts)
            {
                List<string> eventNames = GetEventsFromConstVaraibles(t);
                for (int j = 0; j < eventNames.Count; j++)
                {
                    string name = eventNames[j];
                    if (myEventNames.Contains(name))
                    {
                        Logger.LogError(string.Format("在类{0}中自身存在名为{1}的事件名，不可重复!", this.GetType().Name, name));
                    }
                    else
                    {
                        myEventNames.Add(name);
                    }
                }
            }
            return myEventNames;
        }

        /// <summary>
        /// 从类中的常量获取事件名的值
        /// </summary>
        /// <returns>The events from const varaibles.</returns>
        /// <param name="t">T.</param>
        protected static List<string> GetEventsFromConstVaraibles(Type t)
        {
            List<string> result = new List<string>();
            System.Reflection.FieldInfo[] infos = t.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);

            foreach (var info in infos)
            {
                string v = (string)info.GetValue(null);
                result.Add(v);
            }
            return result;
        }
    }
}

